package com.microcore.service.tree;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 该类主要是测试遍历多叉树
 *
 * @author FengJie
 * @date 2018/4/24
 */

@AllArgsConstructor
@Data
public class Tree {
    private String id;
    private String pId;
    private String children;

    /**
     * 运算类型
     * 0 与
     * 1 或
     */
    private Integer type;

    private boolean result;

    static Map<String, Tree> treeMap = new HashMap<>();


    public static void main(String[] args) {
        List<Tree> list = getList();
        for (Tree tree : list) {
            treeMap.put(tree.getId(), tree);
        }
        System.out.println(diagnosisTree(getList()));
    }

    /**
     * 查找最低端的叶子节点
     */
    static boolean diagnosisTree(List<Tree> treeList) {
        boolean result = false;
        for (Tree tree : treeList) {
            if ("".equals(tree.getChildren())) {
                result = recursivePTree(tree);
                break;
            }
        }
        return result;
    }

    /**
     * 根据叶子节点 递归逻辑节点
     */
    static boolean recursivePTree(Tree tree) {
        //当前叶子
        boolean thisTree = tree.getResult();
        Tree pTree = treeMap.get(tree.getPId());
        if (null != pTree) {
            List<Tree> brothers = getBrothers(tree, pTree);
            for (Tree b : brothers) {
                //这里是需要去获取兄弟的值
                if ((pTree.getType() == 0 && thisTree) || (pTree.getType() == 1 && !thisTree)) {
                    boolean b1 = recursiveChildren(b);
                    thisTree = algorithm(pTree.getType(), thisTree, b1);
                    pTree.setResult(thisTree);
                    //直接返回当前树的值
                }
            }
            pTree.setResult(thisTree);
            return recursivePTree(pTree);
        }
        return thisTree;
    }

    static boolean algorithm(Integer type, boolean x, boolean y) {
        if (type == 0) {
            return x && y;
        } else {
            return x || y;
        }
    }

    //获取兄弟节点
    static List<Tree> getBrothers(Tree thisTree, Tree pTree) {
        List<Tree> treeList = new ArrayList<>();
        String children = pTree.getChildren();
        String[] split = children.split(",");
        for (String s : split) {
            if ((!s.equals(thisTree.getId())) && (!"".equals(s))) {
                treeList.add(treeMap.get(s));
            }
        }
        return treeList;
    }

    //获取儿子节点
    static List<Tree> getChildren(Tree tree) {
        String children = tree.getChildren();
        String[] split = children.split(",");
        List<Tree> treeList = new ArrayList<>();
        for (String s : split) {
            if (!"".equals(s)) {
                treeList.add(treeMap.get(s));
            }
        }
        return treeList;
    }

    /**
     * 递归叶子节点
     */
    static boolean recursiveChildren(Tree tree) {
        List<Tree> children = getChildren(tree);
        //处理的是没有子节点情况
        if (children.size() == 0) {
            return tree.getResult();
        } else {
            for (Tree c : children) {
                boolean isLeaf = StringUtils.isEmpty(c.getChildren());
                boolean nodeStatus;
                if (isLeaf) {
                    nodeStatus = c.getResult();
                } else {
                    nodeStatus = recursiveChildren(c);
                }
                if (tree.getType() == 0) {
                    if (nodeStatus) {
                        c.setResult(true);
                    } else {
                        return false;
                    }
                } else if (tree.getType() == 1) {
                    if (nodeStatus) {
                        return true;
                    } else {
                        c.setResult(false);
                    }
                }
            }
        }
        return tree.getResult();
    }

    static List<Tree> getList() {
        Tree tree0 = new Tree("1.1", "-1", "2.1,2.2", 0, true);
        Tree tree1 = new Tree("2.1", "1.1", "3.1,3.2", 1, false);
        Tree tree2 = new Tree("2.2", "1.1", "3.3,3.4", 1, false);
        Tree tree3 = new Tree("3.1", "2.1", "4.1,4.2", 0, true);
        Tree tree4 = new Tree("3.2", "2.1", "", 1, true);
        Tree tree5 = new Tree("3.3", "2.2", "4.3,4.4", 1, false);
        Tree tree6 = new Tree("3.4", "2.2", "4.5,4.6,4.7", 0, false);
        Tree tree7 = new Tree("4.1", "3.1", "", 1, true);
        Tree tree8 = new Tree("4.2", "3.1", "", 1, true);
        Tree tree9 = new Tree("4.3", "3.3", "5.1,5.2", 0, false);
        Tree tree10 = new Tree("4.4", "3.3", "", 1, false);
        Tree tree11 = new Tree("4.5", "3.4", "", 1, true);
        Tree tree12 = new Tree("4.6", "3.4", "", 1, false);
        Tree tree13 = new Tree("4.7", "3.4", "", 1, true);
        Tree tree14 = new Tree("5.1", "4.3", "", 1, true);
        Tree tree15 = new Tree("5.2", "4.4", "", 1, true);
        List<Tree> treeList = new ArrayList<>();
        treeList.add(tree0);
        treeList.add(tree1);
        treeList.add(tree2);
        treeList.add(tree3);
        treeList.add(tree4);
        treeList.add(tree5);
        treeList.add(tree6);
        treeList.add(tree7);
        treeList.add(tree8);
        treeList.add(tree9);
        treeList.add(tree10);
        treeList.add(tree11);
        treeList.add(tree12);
        treeList.add(tree13);
        treeList.add(tree14);
        treeList.add(tree15);
        return treeList;
    }

    boolean getResult() {
        return result;
    }


}
